package com.example.im.infra.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * @author PC
 * json工具类
 */
public class JsonUtils {
    private final static Logger logger = LoggerFactory.getLogger(JsonUtils.class);
    static final ObjectMapper OBJECT_MAPPER;

    static {
        OBJECT_MAPPER = new ObjectMapper();

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        OBJECT_MAPPER.registerModule(javaTimeModule);
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static ObjectMapper getObjectMapper() {
        return OBJECT_MAPPER;
    }

    /**
     * object转json
     *
     * @param objectMapper 对象映射
     * @param data         对象
     * @return json
     */
    public static String toJson(ObjectMapper objectMapper, Object data) {
        String result = null;
        try {
            result = objectMapper.writeValueAsString(data);
        } catch (JsonProcessingException e) {
            logger.error("error.to_json ", e);
        }
        return result;
    }

    /**
     * object转json
     *
     * @param data 对象
     * @return json
     */
    public static String toJson(Object data) {
        return toJson(getObjectMapper(), data);
    }

    /**
     * json转object
     *
     * @param json          json
     * @param typeReference 类型引用
     * @param <T>           泛型
     * @return 对象
     */
    public static <T> T toObjectByTypeReference(String json, TypeReference<T> typeReference) {
        return toObjectByTypeReference(getObjectMapper(), json, typeReference);
    }

    /**
     * json转object
     *
     * @param objectMapper  对象映射
     * @param json          json
     * @param typeReference 类型引用
     * @param <T>           泛型
     * @return 对象
     */
    public static <T> T toObjectByTypeReference(ObjectMapper objectMapper, String json, TypeReference<T> typeReference) {
        T t = null;
        try {
            t = objectMapper.readValue(json, typeReference);
        } catch (IOException e) {
            logger.error("error.to_object ", e);
        }
        return t;
    }

    /**
     * json转object
     *
     * @param objectMapper 对象映射
     * @param json         json
     * @param clazz        类
     * @param <T>          泛型
     * @return 对象
     */
    public static <T> T toObjectByClass(ObjectMapper objectMapper, String json, Class<T> clazz) {
        T t = null;
        try {
            t = objectMapper.readValue(json, clazz);
        } catch (IOException e) {
            logger.error("error.to_object ", e);
        }
        return t;
    }

    /**
     * json转object
     *
     * @param json  json
     * @param clazz 类
     * @param <T>   泛型
     * @return 对象
     */
    public static <T> T toObjectByClass(String json, Class<T> clazz) {
        return toObjectByClass(getObjectMapper(), json, clazz);
    }
}
